// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.api.ads.tools.jaxws;

import com.google.common.annotations.VisibleForTesting;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

/**
 * Takes the properties of an API from the Java client library and pulls out
 * pertinent information.
 *
 * @author Joseph DiLallo
 */
public class ApiProperties {

  private String apiName;
  private Properties properties;

  /**
   * Reads in properties from the given path.
   *
   * @param apiName The name of the API whose properties this encapsulates
   * @param propertiesFilePath The fully qualified path to the API's properties
   *     file
   */
  public ApiProperties(String apiName, String propertiesFilePath) {
    this.apiName = apiName;
    properties = new Properties();
    try {
      FileReader inputFile = new FileReader(new File(propertiesFilePath));
      properties.load(inputFile);
      inputFile.close();
    } catch (IOException e) {
      throw new IllegalStateException("Unable to load properties file.", e);
    }
  }

  /**
   * Testable constructor.
   *
   * @param apiName The name of the API whose properties this encapsulates
   * @param properties The properties for this API
   */
  @VisibleForTesting
  ApiProperties(String apiName, Properties properties) {
    this.apiName = apiName;
    this.properties = properties;
  }

  /**
   * Replaces the string "${api.framework}" in the package prefix with the API
   * framework in use.
   *
   * @param apiFramework The framework to substitute into the package prefix
   */
  public void correctPackagePrefix(String apiFramework) {
    properties.setProperty("api." + apiName + ".package.prefix",
        properties.getProperty("api." + apiName + ".package.prefix")
            .replace("${api.framework}", apiFramework));
  }

  /**
   * Extracts the WSDL postfix property.
   */
  public String getWsdlPostfix() {
    return properties.getProperty("api." + apiName + ".wsdl.postfix");
  }

  /**
   * Extracts the package prefix property.
   */
  public String getPackagePrefix() {
    return properties.getProperty("api." + apiName + ".package.prefix");
  }

  /**
   * Extracts the production server URL property.
   */
  public String getServerUrl() {
    return properties.getProperty("api." + apiName + ".server.production");
  }

  /**
   * Extracts the property listing the versions of the API.
   */
  public String[] getVersions() {
    return properties.getProperty("api." + apiName + ".versions").split(",");
  }

  /**
   * Extracts the property indicating whether the API uses groups or not.
   */
  public String hasGroups(String version) {
    return properties.getProperty(getVersionedPropertyPrefix() + version + ".hasgroups");
  }

  /**
   * Extracts the property listing the groups of the API.
   */
  public String[] getGroups(String version) {
    return properties.getProperty(getVersionedPropertyPrefix() + version + ".groups").split(",");
  }

  /**
   * Extracts the property listing services of a version of the API.
   */
  public String[] getServices(String version) {
    return properties.getProperty(getVersionedPropertyPrefix() + version
        + ".services").split(",");
  }

  /**
   * Extracts the property listing services in a group in a version of the API.
   */
  public String[] getServices(String version, String group) {
    return properties.getProperty(getVersionedPropertyPrefix() + version + "."  + group
        + ".services").split(",");
  }

  /**
   * Gets the property name prefix used for versioned properties.
   */
  private String getVersionedPropertyPrefix() {
    return "api." + apiName + ".version.";
  }
}
